/**
 * 1. Promise是一个类或者构造函数，接收一个函数作为参数。这个函数称为执行器
 * 2. 实例化Promise时，执行器函数立即执行，并接收两个参数：resolve和reject。这两个函数都是Promise类内部提供的。
 * 3. Promise的状态变化：pending → fulfilled或者pending → rejected。状态改变是resolve和reject函数调用时发生的。
 *    执行器函数中resolve函数调用时，promise状态由pending变为fulfilled；reject函数调用时，promise状态由pending变为rejected。
 * 4. then方法是在promise的实例上调用的，接收两个函数作为参数，第一个函数数是状态变为fulfilled时调用，其参数是resolve调用时传入的值；第二个参数是状态变为rejected时调用，其参数是reject函数调用时传入的值。
 * 5. 添加异步逻辑，在pending状态时，先把fulfillCallback和rejectCallback先存起来，等resolve或reject函数执行时，再调用相应的回调。可以理解成then方法作用其实是注册回调函数，供promise状态变化时调用。
 * 6. then方法可以链式调用，说明then方法调用后的返回值是一个promise。then方法链式调用时，下一个then方法的回调函数的入参，就是上一个then方法的回调函数的返回值。
*/
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
  constructor(executor) {
    executor(this._resolve, this._reject)
  }

  _status = PENDING // promise状态
  value = undefined // 存储resolve执行时传入的值
  reason = undefined // 存储reject执行时传入的值，即失败的原因

  fulfillCallback = []
  rejectCallback = []

  //作用有两个，改变promise对象的状态，把传进来的值保存在对象中，供then方法回调使用 
  _resolve = (value) => {
    if (this._status !== PENDING) return
    this.value = value
    this._status = FULFILLED
    // this.fulfillCallback && this.fulfillCallback(this.value)
    while (this.fulfillCallback.length) {
      this.fulfillCallback.shift()(this.value)
    }
  }
  _reject = (reason) => {
    if (this._status !== PENDING) return
    this.reason = reason
    this._status = REJECTED
    // this.rejectCallback && this.rejectCallback(this.reason)
    while (this.rejectCallback.length) {
      this.rejectCallback.shift()(this.reason)
    }
  }

  then = (fulfillCallback, rejectCallback) => {
    let promise = new MyPromise((resolve, reject) => {
      if (this._status === FULFILLED) {
        const resVal = fulfillCallback(this.value)
        // 判断resVal是普通值还是promise
        // resolve(resVal)
        resolvePromise(resVal, resolve, reject)
      }
      if (this._status === REJECTED) {
        rejectCallback(this.reason)
      }
      this.fulfillCallback.push(fulfillCallback)
      this.rejectCallback.push(rejectCallback)
    })
    return promise
  }
}

function resolvePromise (resVal, resolve, reject) {
  console.log('fsdfds')
  if (resVal instanceof MyPromise) {
    // resVal.then((val) => { resolve(val) }, (reason) => { resolve(reason) })
    resVal.then(resolve, reject)
  } else {
    resolve(resVal)
  }
}

const promise = new MyPromise((res, rej) => {
  setTimeout(() => {
    res('成功')
    // rej('失败')
  }, 1000)
})
const promise2 = new MyPromise((res, rej) => {
  setTimeout(() => {
    res('成功ll')
    // rej('失败')
  }, 1000)
})

// promise.then(value => console.log('1', value), reason => console.log(reason))
// promise.then(value => console.log('2', value), reason => console.log(reason))
// promise.then(value => console.log('3', value), reason => console.log(reason))

promise
  .then(val => { console.log(val); return 100 })
  .then(val => { console.log(val); return promise2 })
  .then(val => console.log(val))